<template>
  <div
    class="chart-box"
    style="width: 100%; height: 100%"
    :style="{ backgroundColor: widgetOptions.setup.backgroundColor }"
  >
    <div v-if="!chartStatus" ref="chartRef" style="width: 100%; height: 100%"></div>

    <ChartEmpty v-if="chartStatus" :chartStatus="chartStatus" />
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import * as echarts from 'echarts'
import { useTools } from '../../hooks/useTools'
import { mapper } from '../constants'
import { useSignalView } from '../../hooks/useSignalView'
import ChartEmpty from '../../components/chartEmpty.vue'

// 接收父组件传入的值
const props = defineProps({
  widgetOptions: {
    type: Object as PropType<Record<string, any>>, // 或更具体的类型
    required: true
  },
  isPreview: {
    type: Boolean,
    default: false
  }
})

const chartRef = ref<HTMLDivElement | null>(null)
let myChart: echarts.ECharts | null = null
const chartData = ref<any>(null)

const cache = ref<any[]>([]) //缓存数据
const maxCacheSize = ref(60) //最大缓存数据条数
const isShowTrendLine = ref(false) //是否显示趋势线

const { toRgba } = useTools()
const mockDataUrl = '/mockdata/realtime/sed.json'

const initChart = () => {
  if (chartRef.value) {
    // 初始化实例
    myChart = echarts.init(chartRef.value)
  }
}

// 更新配置
const updateOptions = () => {
  if (!chartData.value) return
  if (cache.value?.length > maxCacheSize.value) {
    cache.value.shift() //缓存数据超过最大缓存数据条数，删除第一条
  }
  cache.value.push(chartData.value) //缓存数据
  const { signalName, startTime, duration, value, extra } = chartData.value
  const signalLabel = mapper[signalName] || ''
  //单个值时，默认使用仪表盘
  const isSingle = (value) => {
    return value?.length === 1
  }
  const keys = Object.keys(value)
  const isSingleFlag = isSingle(keys)
  const seriesData = Object.values(value)
  let option
  if (isSingleFlag) {
    const cacheData = cache.value.map((item) => {
      return [item.startTime, item.value[keys[0]]]
    })
    const series = isShowTrendLine.value
      ? {
          type: 'line',
          data: cacheData,
          smooth: false,
          showSymbol: false,
          animation: false
        }
      : {
          type: 'gauge',
          gridIndex: 0,
          progress: {
            show: true
          },
          min: 0,
          max: 1,
          detail: {
            valueAnimation: true,
            formatter: '{value}'
          },
          data: [
            {
              value: seriesData[0],
              name: keys[0]
            }
          ]
        }
    option = {
      title: {
        text: `${signalLabel}`,
        subtext: `开始时间：${startTime}`,
        left: 'center',
        textStyle: {
          color: props.widgetOptions.setup.titleColor,
          fontSize: props.widgetOptions.setup.titleFontSize
        },
        subtextStyle: {
          color: props.widgetOptions.setup.subtitleColor,
          fontSize: props.widgetOptions.setup.subtitleFontSize
        }
      },
      tooltip: {
        show: isShowTrendLine.value,
        trigger: 'axis'
      },
      xAxis: {
        type: 'time',
        show: isShowTrendLine.value,
        axisLabel: {
          color: props.widgetOptions.setup.xFontColor,
          fontSize: props.widgetOptions.setup.xFontSize
        }
      },
      yAxis: {
        show: isShowTrendLine.value,
        axisLabel: {
          color: props.widgetOptions.setup.yFontColor,
          fontSize: props.widgetOptions.setup.yFontSize
        }
      },
      series,
      graphic: [
        {
          type: 'text',
          left: 50,
          top: 20,
          style: {
            text: isShowTrendLine.value ? '返回' : '查看趋势',
            fontSize: props.widgetOptions.setup.viewFontSize,
            color: props.widgetOptions.setup.viewFontColor
          },
          onclick: function () {
            isShowTrendLine.value = !isShowTrendLine.value
          }
        }
      ]
    }
  } else {
    const xData = keys
    const series: any[] = []
    if (isShowTrendLine.value) {
      keys.forEach((key) => {
        series.push({
          type: 'line',
          name: key,
          data: cache.value.map((item) => {
            return [item.startTime, item.value[key]]
          }),
          smooth: false,
          showSymbol: false,
          animation: false
        })
      })
    } else {
      series.push({
        type: 'bar',
        //realtimeSort: true,
        data: seriesData,
        label: {
          show: true,
          position: 'right'
        },
        smooth: false,
        showSymbol: false,
        itemStyle: {
          color: props.widgetOptions.setup.barColor
        }
      })
    }
    option = {
      title: {
        text: `${signalLabel}`,
        subtext: `开始时间：${startTime}`,
        left: 'center',
        textStyle: {
          color: props.widgetOptions.setup.titleColor,
          fontSize: props.widgetOptions.setup.titleFontSize
        },
        subtextStyle: {
          color: props.widgetOptions.setup.subtitleColor,
          fontSize: props.widgetOptions.setup.subtitleFontSize
        }
      },
      tooltip: {
        trigger: 'axis'
      },
      legend: {
        show: isShowTrendLine.value,
        data: keys,
        orient: 'vertical',
        left: 'left',
        top: 'center',
        selectedMode: 'single'
      },
      xAxis: isShowTrendLine.value
        ? {
            type: 'time',
            axisLine: {
              show: true,
              lineStyle: {
                color: props.widgetOptions.setup.xLineColor
              }
            },
            axisLabel: {
              color: props.widgetOptions.setup.xFontColor,
              fontSize: props.widgetOptions.setup.xFontSize
            }
          }
        : {
            type: 'value',
            splitLine: {
              show: false
            },
            axisTick: {
              show: false
            },
            axisLabel: {
              color: props.widgetOptions.setup.xFontColor,
              fontSize: props.widgetOptions.setup.xFontSize
            }
          },
      yAxis: isShowTrendLine.value
        ? {
            type: 'value',
            axisLabel: {
              color: props.widgetOptions.setup.yFontColor,
              fontSize: props.widgetOptions.setup.yFontSize
            },
            splitLine: {
              show: props.widgetOptions.setup.ySplitLine,
              lineStyle: {
                color: 'rgba(255,255,255,0.2)'
              }
            }
          }
        : {
            type: 'category',
            data: xData,
            inverse: true,
            axisLabel: {
              color: props.widgetOptions.setup.yFontColor,
              fontSize: props.widgetOptions.setup.yFontSize
            },
            splitLine: {
              show: props.widgetOptions.setup.ySplitLine,
              lineStyle: {
                color: 'rgba(255,255,255,0.2)'
              }
            }
          },
      series,
      graphic: [
        {
          type: 'text',
          left: 50,
          top: 20,
          style: {
            text: isShowTrendLine.value ? '返回' : '查看趋势',
            fontSize: props.widgetOptions.setup.viewFontSize,
            fill: props.widgetOptions.setup.viewFontColor
          },
          onclick: function () {
            isShowTrendLine.value = !isShowTrendLine.value
          }
        }
      ]
    }
  }

  myChart?.setOption(option)
  myChart?.resize()
}

const resolveData = (data: any) => {
  if (data && data.msgPack) {
    chartStatus.value = ''
    chartData.value = data.msgPack
    updateOptions()
  } else {
    chartStatus.value = 'noData'
    chartData.value = null
  }
}

const resolveMockData = (data: any) => {
  chartData.value = data
  updateOptions()
}

const { chartStatus, refreshData } = useSignalView(
  props.widgetOptions,
  props.isPreview,
  mockDataUrl,
  resolveData,
  resolveMockData
)

onMounted(() => {
  initChart()
  refreshData()
})

// 如果父组件传入的 props.value 改变，需要更新折线图颜色等
watch(
  () => props.widgetOptions,
  () => {
    if (myChart) {
      updateOptions()
    }
  },
  { immediate: true, deep: true }
)

onBeforeUnmount(() => {
  if (myChart) {
    myChart.dispose()
  }
})
</script>

<style scoped></style>
